//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Windows;
using System.Windows.Controls.Primitives;

namespace OpenLS.Spreadsheet.UI.Internals
{
    public class EditionElement
    {
        public static readonly RoutedEvent CellEditedEvent = EventManager.RegisterRoutedEvent("CellEdited",
                                                                                           RoutingStrategy.
                                                                                               Bubble,
                                                                                           typeof(
                                                                                               EventHandler<CellRoutedEventArgs>),
                                                                                           typeof(
                                                                                               EditionElement));


        public static Cell GetHoverCell(DependencyObject obj)
        {
            return (Cell)obj.GetValue(HoverCellProperty);
        }

        public static void SetHoverCell(DependencyObject obj, Cell value)
        {
            obj.SetValue(HoverCellProperty, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HoverCellProperty =
            DependencyProperty.RegisterAttached("HoverCell", typeof(Cell), typeof(EditionElement), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));


        internal static void SetIsEndModeFor (DependencyObject sender, bool b)
        {
            var v = EditionElement.GetEditorRoot((DependencyObject)sender);
            Window window = Window.GetWindow((DependencyObject)sender);
            if (!b)
            {
                v.ClearValue(EditionElement.IsInEndModeProperty);
                if (window != null)
                    window.ClearValue(EditionElement.IsInEndModeProperty);
            }
            else
            {
                EditionElement.SetIsInEndMode(v, true);
                if (window != null)
                    EditionElement.SetIsInEndMode(window, true);

            }

        }

        internal static ExecutedCommand GetLastExecutedCommand(DependencyObject obj)
        {
            return (ExecutedCommand)obj.GetValue(LastExecutedCommanddProperty);
        }

        internal static void SetLastExecutedCommand(DependencyObject obj, ExecutedCommand value)
        {
            obj.SetValue(LastExecutedCommanddProperty, value);
        }

        // Using a DependencyProperty as the backing store for LastExecutedCommand.  This enables animation, styling, binding, etc...
        internal static readonly DependencyProperty LastExecutedCommanddProperty =
            DependencyProperty.RegisterAttached("LastExecutedCommandastExecutedCommand", typeof(ExecutedCommand), typeof(EditionElement), new FrameworkPropertyMetadata(null));


        public static readonly DependencyProperty EditedCellProperty =
            DependencyProperty.RegisterAttached("EditedCell", typeof (EditedCell), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits, OnEditedCellChanged));

        private static void OnEditedCellChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is FrameworkElement))
                return;
            FrameworkElement element = (FrameworkElement) d;

        }

        public static readonly DependencyProperty EditorProperty =
            DependencyProperty.RegisterAttached("Editor", typeof (TextBoxBase), typeof (EditionElement),
                                                new UIPropertyMetadata(null));

        public static readonly DependencyProperty EditorRootProperty =
            DependencyProperty.RegisterAttached("EditorRoot", typeof (FrameworkElement), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty FocusGridProperty =
            DependencyProperty.RegisterAttached("FocusGrid", typeof (FrameworkElement), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty IsInEndModeProperty =
            DependencyProperty.RegisterAttached("IsInEndMode", typeof (bool), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(false,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty ParameterProperty =
            DependencyProperty.RegisterAttached("Parameter", typeof (ParameterInfo), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty PreferencesProperty =
            DependencyProperty.RegisterAttached("Preferences", typeof (object), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty SelectorProperty =
            DependencyProperty.RegisterAttached("Selector", typeof (Selector), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static readonly DependencyProperty WorkbookOwnerProperty =
            DependencyProperty.RegisterAttached("WorkbookOwner", typeof (FrameworkElement), typeof (EditionElement),
                                                new FrameworkPropertyMetadata(null,
                                                                              FrameworkPropertyMetadataOptions.Inherits));

        public static bool GetIsInEndMode(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsInEndModeProperty);
        }

        public static void SetIsInEndMode(DependencyObject obj, bool value)
        {
            obj.SetValue(IsInEndModeProperty, value);
        }

        // Using a DependencyProperty as the backing store for IsInEndMode.  This enables animation, styling, binding, etc...


        internal static EditionMode GetMode(DependencyObject obj)
        {
            EditedCell editedCell = GetEditedCell(obj);
            if (editedCell == null)
                return EditionMode.Enter; //\\
            return editedCell.Mode;
        }


        internal static void SetEditedCellFor(object child, EditedCell value)
        {
            DependencyObject e = GetEditorRoot((DependencyObject) child);
            WorksheetViewModel wvm = SpreadsheetElement.GetWorksheetViewModel((DependencyObject)child);
            if (wvm != null)
                wvm.Formula = value != null ? value.Formula : null;
            if (value != null)
            {
                SetEditedCellFor(child, null);
            }
            SetEditedCell(e, value);
        }

        public static DependencyObject GetEditorRoot(DependencyObject obj)
        {
            return (FrameworkElement) obj.GetValue(EditorRootProperty);
        }

        public static void SetEditorRoot(DependencyObject obj, DependencyObject value)
        {
            obj.SetValue(EditorRootProperty, value);
        }

        // Using a DependencyProperty as the backing store for EditorRoot.  This enables animation, styling, binding, etc...


        public static EditedCell GetEditedCell(DependencyObject obj)
        {
            return (EditedCell) obj.GetValue(EditedCellProperty);
        }

        public static void SetEditedCell(DependencyObject obj, EditedCell value)
        {
            var oldValue = GetEditedCell(obj);
            if (oldValue == value)
                return;
            if (oldValue != null && value != null)
            {
                // Contract.Assert(false);
            }
            obj.SetValue(EditedCellProperty, value);
            WorksheetViewModel wvm = SpreadsheetElement.GetWorksheetViewModel((DependencyObject)obj);
            if (wvm != null)
                wvm.Formula = value != null ? value.Formula : null;
            FrameworkElement element = (FrameworkElement) obj;
            element.RaiseEvent(new CellRoutedEventArgs(CellEditedEvent, value != null ? value.Cell : null));

        }

        // Using a DependencyProperty as the backing store for EditedCell.  This enables animation, styling, binding, etc...


        public static ParameterInfo GetParameter(DependencyObject obj)
        {
            return (ParameterInfo) obj.GetValue(ParameterProperty);
        }

        public static void SetParameter(DependencyObject obj, ParameterInfo value)
        {
            obj.SetValue(ParameterProperty, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...


        public static TextBoxBase GetEditor(DependencyObject obj)
        {
            return (TextBoxBase) obj.GetValue(EditorProperty);
        }

        public static void SetEditor(DependencyObject obj, TextBoxBase value)
        {
            obj.SetValue(EditorProperty, value);
        }

        // Using a DependencyProperty as the backing store for Editor.  This enables animation, styling, binding, etc...


        public static Selector GetSelector(DependencyObject obj)
        {
            return (Selector) obj.GetValue(SelectorProperty);
        }

        public static void SetSelector(DependencyObject obj, Selector value)
        {
            obj.SetValue(SelectorProperty, value);
        }

        // Using a DependencyProperty as the backing store for Selector.  This enables animation, styling, binding, etc...


        public static FrameworkElement GetFocusGrid(DependencyObject obj)
        {
            return (FrameworkElement) obj.GetValue(FocusGridProperty);
        }

        public static void SetFocusGrid(DependencyObject obj, FrameworkElement value)
        {
            if (obj != null)
                obj.SetValue(FocusGridProperty, value);
        }

        // Using a DependencyProperty as the backing store for FocusGrid.  This enables animation, styling, binding, etc...


        public static FrameworkElement GetWorkbookOwner(DependencyObject obj)
        {
            return (FrameworkElement) obj.GetValue(WorkbookOwnerProperty);
        }

        public static void SetWorkbookOwner(DependencyObject obj, FrameworkElement value)
        {
            obj.SetValue(WorkbookOwnerProperty, value);
        }

        // Using a DependencyProperty as the backing store for WorkbookOwner.  This enables animation, styling, binding, etc...


        public static object GetPreferences(DependencyObject obj)
        {
            return obj.GetValue(PreferencesProperty);
        }

        public static void SetPreferences(DependencyObject obj, object value)
        {
            obj.SetValue(PreferencesProperty, value);
        }

        // Using a DependencyProperty as the backing store for Preferences.  This enables animation, styling, binding, etc...
    }
}